window.resizeTo(650, 590);

var args = [], cmd = JumpToFile.commandLine, data, rx = /\"([^\"]+)\"/g;

while(data = rx.exec(cmd)){
	args.push(data[1]);
}

var configDir   = args[1],
	appDir      = args[2],
	project     = args[3],
	fso         = new ActiveXObject('Scripting.FileSystemObject'),
	pContents   = getFileContents(configDir + '\\project_u.ini', -1),
	ini         = {},
	ignorePaths = /\.svn|\.(jpg|gif|png|zip|rar|psd)$/,
	shell       = new ActiveXObject('WScript.Shell'),
	curConfig, param;


Number.prototype.toJSON = function(){ return isFinite(this) ? this.toString() : 'null'; };
String.prototype.toJSON = function(){ return '"' + this.replace(/\\/g, '\\\\').replace(/\"/g, '\"') + '"'; };
Date.prototype.toJSON   = function(){ return 'new Date(' + this.getTime() + ')'; };

function toJSON(object) {
	if (object.toJSON){
		return object.toJSON();
	}

	var results = [];
	for (var property in object) {
		var value = toJSON(object[property]);
		if (value !== undefined){
			results.push(property.toJSON() + ': ' + value);
		}
	}
	return '{' + results.join(', ') + '}';
}

// parse the INI file
for(var i=0, l=pContents.length; i<l; i++){
	var line = pContents[i];
	if(line.indexOf('[Project\\')==0){
		if(curConfig && curConfig.Name){
			ini[curConfig.Name] = curConfig;
		}
		curConfig = {};
		continue;
	}
	if(!curConfig){ continue; }
	param = line.split('=');
	curConfig[param[0]] = param[1];
}
if(curConfig && curConfig.Name){
	ini[curConfig.Name] = curConfig;
}

// die if project config not found
var config = ini[project];
if(!config){
	alert('No config exists for this project');
	window.close();
}

// attempt to load cached file list
var counter = 0, loc, root = {}, files = [];
var JSON = getFileContents(configDir + '\\' + project + '_contents.json');

// load from cache
if(JSON){
	root = eval('(' + JSON + ')');

	// translate the config list into a hash
	var configItems = {};
	while(loc = config[counter++]){
		configItems[loc] = 1;
	}

	// remove any items that are no longer in the config
	for(var n in root){
		if(!configItems[n]){ delete root[n]; }
	}

	// re-scan existing items
	reScan();

	// add items that are new in the config
	counter = 0;
	while(loc = config[counter++]){
		if(!root[loc]){
			parseLocation(loc);
		}
	}

	generateFileList(root, files, '');
	writeFile(configDir + '\\' + project + '_contents.json', toJSON(root));
}else{
	// get a list of all files in project
	while(loc = config[counter++]){
		parseLocation(loc);
	}
	generateFileList(root, files, '');
	writeFile(configDir + '\\' + project + '_contents.json', toJSON(root));
}
setInterval(reScan, 30000);

function reScan(){
	if(rescanFolders(root, '')){
		files = [];
		generateFileList(root, files, '');
		$fileNames.setOptions({data : files});
		writeFile(configDir + '\\' + project + '_contents.json', toJSON(root));
	}
}

function getFileContents(path, tristate){
	if(!fso.FileExists(path)){ return; }

	var file     = fso.OpenTextFile(path, 1, false, tristate || 0),
	    contents = file.ReadAll().split('\r\n');

	file.Close();

	return contents;
}

function writeFile(path, contents){
	var file = fso.CreateTextFile(path);
	file.write(contents);
}

function rescanFolders(folder, path){
	var modified = false, rescan = [], d;
	for(var n in folder){
		if(folder[n] == 1 || n == '__modifiedAt'){ continue; }
		var F = fso.getFolder(path + n + '\\');
		if(folder[n].__modifiedAt != (d = (F.DateLastModified+''))){
			modified = true;
			rescan.push([F, folder[n]]);
			folder[n].__modifiedAt = d;
		}
		modified = rescanFolders(folder[n], path + n + '\\') || modified;
	}

	for(var i=0, l=rescan.length; i<l; i++){
		var ary = rescan[i], F = ary[0], folder = ary[1];
		for(var n in folder){
			// delete file cache for this folder
			if(folder[n] === 1){ delete folder[n]; }
		}

		var subFiles = F.files;
		for(var fEnum = new Enumerator(subFiles); !fEnum.atEnd(); fEnum.moveNext()){
			var path = fEnum.item().Name;
			if(ignorePaths.test(path)){ continue; }

			folder[path] = 1;
		}
	}

	return modified;
}

function generateFileList(folder, files, path){
	for(var n in folder){
		if(n=='__modifiedAt'){ continue; }
		if(folder[n] == 1){ files.push(path+n); }
		generateFileList(folder[n], files, path + n + '\\');
	}
}

function parseLocation(loc){
	try{
		var file = fso.GetFile(loc);
		root[file.Path] = 1;
	}catch(e){
		var folder  = fso.GetFolder(loc);
		parseFolder(folder, root, true);
	}
}

function parseFolder(folder, root, firstNode){
	var subFiles   = folder.Files,
		subFolders = folder.SubFolders,
		curFolder  = root[firstNode ? folder.Path : folder.Name] = {};

	curFolder.__modifiedAt = folder.DateLastModified + '';

	for(var fEnum = new Enumerator(subFiles); !fEnum.atEnd(); fEnum.moveNext()){
		var path = fEnum.item().Name;
		if(ignorePaths.test(path)){ continue; }

		curFolder[path] = 1;
	}

	for(var fEnum = new Enumerator(subFolders); !fEnum.atEnd(); fEnum.moveNext()){
		if(ignorePaths.test(fEnum.item().Path)){ continue; }

		parseFolder(fEnum.item(), curFolder);
	}
}

function loadFile(path){
	shell.exec('"' + appDir + '\\editplus.exe" "' + path + '"');
}

var $fileNames;
$(function(){
	$fileNames = $("#fileName")
		.autocomplete(files, {matchContains : true, max : 25})
		.bind('result', function(v, v){
			loadFile(this.value);
			this.value = '';
		});
	$fileNames[0].focus();
});